package indi.zjh.dp.orm.chart;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.dom4j.DocumentException;

import indi.zjh.dp.db.Configuration;
import indi.zjh.dp.orm.RelationClass;
import indi.zjh.dp.util.FileUtil;
import indi.zjh.dp.vc.Commit;
import indi.zjh.dp.vc.Version;
import indi.zjh.dp.vc.VersionControl;

public class Chart {
	protected Version version;
	
	/*
@startuml
Class01 <|-- Class02 : 继承
Class03 *-- Class04 : 组合
Class05 o-- Class06 : 聚合
Class07 .. Class08 : 关联

class Class01 {
  String data
  void methods()
}

@enduml
	 */
	public Chart(Version version)
	{
		this.version = version;
	}
	
	private String preDraw()
	{
		StringBuffer sb = new StringBuffer();
		sb.append("<html>\n");
		sb.append("<head>\n");
		sb.append("<meta charset=\"utf-8\">");
		sb.append("<script type=\"text/javascript\" src=\"/version?t=jquery.js\"></script>\n");
		sb.append("<script type=\"text/javascript\" src=\"/version?t=jquery_plantuml.js\"></script>\n");
		sb.append("</head>\n");
		sb.append("<body>\n");
		sb.append("<hr>\n");
		sb.append("<a href=\"/version?t=index.html\">返回版本列表</a><hr>");

		return sb.toString();
	}
	
	private String postDraw()
	{
		StringBuffer sb1 = new StringBuffer();
		sb1.append("</body>\n");
		sb1.append("</html>\n");
		return sb1.toString();
	}
	
	private String draw()
	{
		StringBuffer sb = new StringBuffer();
		
		sb.append("<img uml=\"\n");
		sb.append("@startuml\n");
		
		Iterator<Map.Entry<String, RelationClass>> iter = this.version.getRelationClassIterator();
		while(iter.hasNext())
		{
			Map.Entry<String, RelationClass> entry = iter.next();
			String classname = entry.getKey();
			RelationClass rc = entry.getValue();
			//System.out.println("classname="+classname+","+rc.getName());
			
			sb.append(rc.getClassDesc());
			
			if(rc.directSubClass.size() > 0)
			{
				Iterator<RelationClass> it = rc.directSubClass.iterator();
				while(it.hasNext())
				{
					RelationClass subrc = it.next();
					sb.append(rc.getName()+" --|> "+subrc.getName()+" : 继承\n");
				}
			}
			if(rc.directContainingClass.size() > 0)
			{
				Iterator<RelationClass> it = rc.directContainingClass.iterator();
				while(it.hasNext())
				{
					RelationClass subrc = it.next();
					sb.append(rc.getName()+" --* "+subrc.getName()+" : 包含\n");
				}
			}
			if(rc.aggregationedClass.size() > 0)
			{
				Iterator<RelationClass> it = rc.aggregationedClass.iterator();
				while(it.hasNext())
				{
					RelationClass subrc = it.next();
					sb.append(subrc.getName()+" --o "+rc.getName()+" : 聚合\n");
				}
			}
			if(rc.associationClass.size() > 0)
			{
				Iterator<RelationClass> it = rc.associationClass.iterator();
				while(it.hasNext())
				{
					RelationClass subrc = it.next();
					sb.append(rc.getName()+" --> "+subrc.getName()+" : 关联\n");
				}
			}
		}
		
		sb.append("@enduml\n");
		sb.append("\">\n");


		return sb.toString();
	}
	
	public void output()
	{
		try
		{
			FileUtil.writeStringFile("relationChart/"+this.version.getTimestamp()+".html", this.preDraw()+this.draw()+this.postDraw());
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}
	
	/**
	 * 更新最新指定的版本数的UML图
	 * @param limit
	 * @throws Exception 
	 * @throws DocumentException 
	 */
	public static void updateVersions(int limit) throws DocumentException, Exception
	{
		String checkoutPath = Configuration.getInstance().getBusiConf().checkoutPath + File.separator + "checkout";
		//System.out.println(checkoutPath);
		List<Commit> commits = VersionControl.getInstance().getCommitList(limit);
		Iterator<Commit> iterator = commits.iterator();
		StringBuffer listHtmlContent = new StringBuffer();
		
		listHtmlContent.append("<html>\n");
		listHtmlContent.append("<head>\n");
		listHtmlContent.append("<meta charset=\"utf-8\">");
		listHtmlContent.append("</head>\n");
		listHtmlContent.append("<body>\n");
		
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		while(iterator.hasNext())
		{
			Commit commit = iterator.next();
			//System.out.println(checkoutPath+File.separator+commit.getTimestamp());
			Version version = commit.checkout(checkoutPath+File.separator+commit.getTimestamp(), true);
			version.analyzeClassRelation();
			Chart chart = new Chart(version);
			chart.output();
			
			Date thisDate = new Date(commit.getTimestamp());
			listHtmlContent.append("<a href=\"/version?t="+commit.getTimestamp()+"\">"+format.format(thisDate)+" "+commit.getDesc()+"</a><br>");
		}
		
		
		listHtmlContent.append("</body>\n");
		listHtmlContent.append("</html>\n");

		
		FileUtil.writeStringFile("relationChart/index.html", listHtmlContent.toString());
	}
	
	public static String getVersionsHtml()
	{
		try
		{
			updateVersions(16);
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		return FileUtil.readStringFromFile("relationChart/index.html");
	}
}
